/**
 * @file    diag_volt.c
 * @brief   电压诊断
 * @author  Liuwei
 * @version 1.0.1
 * @date    2023-04-19
 * 
 * @copyright Copyright (c) 2023 JBD-Energy Storage Technology Co. LTD
 * 
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version   <th>Author   <th>Description
 * <tr><td>2023-04-19 <td>1.0.1     <td>Liuwei   <td>首次创建
 * </table>
 */

/* includes ------------------------------------------------------------------*/
#include "diag_volt.h"
#include "diagnosis.h"
#include "param_mng.h"
#include "sample.h"
#include "soc_calc.h"
#include "var_mng.h"
#include "event_mng.h"
#include "cfg_prj.h"
#include "base_math.h"
/* macro/define --------------------------------------------------------------*/
#define COV_ALM_RECV_SOC            (98)
#define FIRST_POW_CUV_DELAY         (60000)  
/* typedef -------------------------------------------------------------------*/

/* local functions -----------------------------------------------------------*/

/* static variables ----------------------------------------------------------*/
static diag_data_type diag_cov_data = {0};
static diag_data_type diag_cuv_data = {0};
static diag_data_type diag_bov_data = {0};
static diag_data_type diag_buv_data = {0};
static diag_data_type diag_vdiff_data = {0};
static uint8_t first_pow_flag = 0;
static uint32_t first_pow_cnt = 0;
extern uint8_t wifi_send_flag;
/* global variables ----------------------------------------------------------*/

/** ------------------------------------------------------------------------- *
  *                             Global function
 ** ------------------------------------------------------------------------- */
/**
 * @brief  单体过压诊断 
 * @param  cycle  : 时间周期
 * @param  sys_state : 系统状态
 * @param  smp_val : 采样值
 */
void diag_volt_cov(uint16_t cycle)
{
    diag_para_type diag_para = {0};
	diag_data_type *p_data = &diag_cov_data;
	uint16_t cov_times = 0;
	float now_curr = 0;
	
	now_curr = sample_get_curr();//var_get_data(VAR_ID_BUS_CURR) * VAR_CURR_FACTOR - VAR_CURR_OFFSET;
	  
	uint8_t sys_state = var_get_data(VAR_ID_CURR_DR);
	uint16_t smp_val = var_get_data(VAR_ID_MAX_CELL_VOLT);
	
    diag_para.alm_param = param_get_data(PAR_ID_COV_ALM_VAL);
    diag_para.alm_recv = param_get_data(PAR_ID_COV_ALM_RCV);
    diag_para.alm_dly = param_get_data(PAR_ID_COV_ALM_DLY);

    diag_para.prp_param = param_get_data(PAR_ID_COV_PRP_VAL);
    diag_para.prp_recv = param_get_data(PAR_ID_COV_PRP_RCV);
    diag_para.prp_dly = param_get_data(PAR_ID_COV_PRP_DLY);
    /* 告警诊断*/
    if(0 == p_data->alm_state)
    {
        if((CURR_DR_DSG != sys_state) && (smp_val >= diag_para.alm_param))
        {
            p_data->alm_time_cnt += cycle;
            if(p_data->alm_time_cnt >= diag_para.alm_dly) 
            {
                p_data->alm_state = 1;
				if((diag_get_prp(PRP_ID_COL) == 0))
				{
					soc_calc_set_soc(10000);
                    diag_set_prp(PRP_ID_FULL_CHG , 1);
					diag_set_alarm(ALM_ID_FCHG , 1);
				}
				event_add_to_sram(EVT_ID_ALM_COV , var_get_data(VAR_ID_MAX_CELL_VOLT) , param_get_data(PAR_ID_COV_ALM_VAL));
                p_data->alm_time_cnt = 0;
				
				wifi_send_flag = 1;
            }   
        }
        else
        {
            p_data->alm_time_cnt = 0;
        }
    }
    else
    {
		/* 电流小于3A 或 SOC低于98%,解除过压告警 */
        if(((var_get_data(VAR_ID_CURR_DR) == CURR_DR_DSG) && (-now_curr > CHG_RECV_CURR)) 
			|| (var_get_data(VAR_ID_DISP_SOC) * 0.01 < FCHG_RECV_SOC)
		    || (smp_val <= diag_para.alm_recv))		
		{
            p_data->alm_state = 0;
            p_data->alm_time_cnt = 0;
        }
    }
    diag_set_alarm(ALM_ID_COV , p_data->alm_state);
    /* 保护诊断 */
    if(0 == p_data->prp_state)
    {
        if((sys_state != CURR_DR_DSG) && (smp_val >= diag_para.prp_param))
        {
            p_data->prp_time_cnt += cycle;
            if(p_data->prp_time_cnt >= diag_para.prp_dly) 
            {
                p_data->prp_state = 1;                
				if((diag_get_prp(PRP_ID_COL) == 0))
				{
					soc_calc_set_soc(10000);
                    diag_set_prp(PRP_ID_FULL_CHG , 1);
					diag_set_alarm(ALM_ID_FCHG , 1);
				}
				cov_times = param_get_data(PAR_ID_COV_PRP_TIMES) + 1;
				param_set_data(PAR_ID_COV_PRP_TIMES , cov_times);
				event_add_to_sram(EVT_ID_PRP_COV , var_get_data(VAR_ID_MAX_CELL_VOLT) , param_get_data(PAR_ID_COV_PRP_VAL));
                p_data->prp_time_cnt = 0;
				
				wifi_send_flag = 1;
            }   
        }
        else
        {
            p_data->prp_time_cnt = 0;
        }
    }
    else
    {
        if(((CURR_DR_DSG == sys_state)&&(-now_curr > CHG_RECV_CURR)) 
		   || (var_get_data(VAR_ID_DISP_SOC) * 0.01 < FCHG_RECV_SOC)
		   || (smp_val <= diag_para.prp_recv))
        {
            p_data->prp_state = 0;
            p_data->prp_time_cnt = 0;
        }
    }

    diag_set_prp(PRP_ID_COV , p_data->prp_state);
}

/**
 * @brief  单体欠压诊断 
 * @param  cycle  : 时间周期
 * @param  sys_state : 系统状态
 * @param  smp_val : 采样值
 */
void diag_volt_cuv(uint16_t cycle)
{
    diag_para_type diag_para = {0};
	diag_data_type *p_data = &diag_cuv_data;
	uint16_t cuv_times = 0;
	uint8_t sys_state = var_get_data(VAR_ID_CURR_DR);
	uint16_t smp_val = var_get_data(VAR_ID_MIN_CELL_VOLT);
	float now_curr = 0;
	
	now_curr = sample_get_curr();//var_get_data(VAR_ID_BUS_CURR) * VAR_CURR_FACTOR - VAR_CURR_OFFSET;

    diag_para.alm_param = param_get_data(PAR_ID_CUV_ALM_VAL);
    diag_para.alm_recv = param_get_data(PAR_ID_CUV_ALM_RCV);
    diag_para.alm_dly = param_get_data(PAR_ID_CUV_ALM_DLY);

    diag_para.prp_param = param_get_data(PAR_ID_CUV_PRP_VAL);
    diag_para.prp_recv = param_get_data(PAR_ID_CUV_PRP_RCV);
    diag_para.prp_dly = param_get_data(PAR_ID_CUV_PRP_DLY);
	
	if(first_pow_flag == 0)
	{
		first_pow_cnt += cycle;
		if(((-now_curr > 5) && (first_pow_cnt >= 10000)) || (first_pow_cnt >= FIRST_POW_CUV_DELAY)) 
		{
			first_pow_cnt = 0;
			first_pow_flag = 1;
		}

	}
	else
	{
		first_pow_cnt = 0;
	}
	
    /* 告警诊断*/
    if(0 == p_data->alm_state)
    {
        if((CURR_DR_CHG != sys_state) && (smp_val <= diag_para.alm_param))
        {
            p_data->alm_time_cnt += cycle;
            if(p_data->alm_time_cnt >= diag_para.alm_dly) 
            {
                p_data->alm_state = 1;
				if((diag_get_prp(PRP_ID_COL) == 0) && (var_get_data(VAR_ID_MIN_CELL_VOLT) > 100))
					soc_calc_set_soc(0);
				event_add_to_sram(EVT_ID_ALM_CUV , var_get_data(VAR_ID_MIN_CELL_VOLT) , param_get_data(PAR_ID_CUV_ALM_VAL));
                p_data->alm_time_cnt = 0;
				wifi_send_flag = 1;
            }   
        }
        else
        {
            p_data->alm_time_cnt = 0;
        }
    }
    else
    {
        if(((CURR_DR_CHG == sys_state)&&(now_curr >= DSG_RECV_CURR)) || (smp_val >= diag_para.alm_recv))
        {
            p_data->alm_state = 0;
            p_data->alm_time_cnt = 0;
        }
    }
    diag_set_alarm(ALM_ID_CUV , p_data->alm_state);
    /* 保护诊断 */
    if(0 == p_data->prp_state)
    {
        if((first_pow_flag)&&(CURR_DR_CHG != sys_state) && (smp_val <= diag_para.prp_param))
        {
            p_data->prp_time_cnt += cycle;
            if(p_data->prp_time_cnt >= diag_para.prp_dly) 
            {
                p_data->prp_state = 1;
                if((diag_get_prp(PRP_ID_COL) == 0) && (var_get_data(VAR_ID_MIN_CELL_VOLT) > 100))
					soc_calc_set_soc(0);
				cuv_times = param_get_data(PAR_ID_CUV_PRP_TIMES) + 1;
				param_set_data(PAR_ID_CUV_PRP_TIMES , cuv_times);
				event_add_to_sram(EVT_ID_PRP_CUV , var_get_data(VAR_ID_MIN_CELL_VOLT) , param_get_data(PAR_ID_CUV_PRP_VAL));
                p_data->prp_time_cnt = 0;
				
				wifi_send_flag = 1;
            }   
        }
        else
        {
            p_data->prp_time_cnt = 0;
        }
    }
    else
    {
        if(((CURR_DR_CHG == sys_state)&&(now_curr >= DSG_RECV_CURR)) 
			|| (smp_val >= diag_para.prp_recv)||(1 == var_get_data(VAR_ID_FAULT_CLEAR_STATE)))
        {
            p_data->prp_state = 0;
            p_data->prp_time_cnt = 0;
			var_set_data(VAR_ID_FAULT_CLEAR_STATE , 0);			
        }
    }

    diag_set_prp(PRP_ID_CUV , p_data->prp_state);
}

/**
 * @brief  总压过压诊断 
 * @param  cycle  : 时间周期
 * @param  sys_state : 系统状态
 * @param  smp_val : 采样值
 */
void diag_volt_bov(uint16_t cycle)
{
    diag_para_type diag_para = {0};
	diag_data_type *p_data = &diag_bov_data;
	uint8_t sys_state = var_get_data(VAR_ID_CURR_DR);
	uint16_t bov_times = 0;
	float smp_val = var_get_data(VAR_ID_BATT_VOLT) * 0.01; 
	float now_curr = 0;
	
	now_curr = sample_get_curr();//var_get_data(VAR_ID_BUS_CURR) * VAR_CURR_FACTOR - VAR_CURR_OFFSET;
    diag_para.alm_param = param_convert_float(PARAM_BVOLT , param_get_data(PAR_ID_BOV_ALM_VAL));
    diag_para.alm_recv = param_convert_float(PARAM_BVOLT ,param_get_data(PAR_ID_BOV_ALM_RCV));
    diag_para.alm_dly = param_get_data(PAR_ID_BOV_ALM_DLY);

    diag_para.prp_param = param_convert_float(PARAM_BVOLT ,param_get_data(PAR_ID_BOV_PRP_VAL));
    diag_para.prp_recv = param_convert_float(PARAM_BVOLT , param_get_data(PAR_ID_BOV_PRP_RCV));
    diag_para.prp_dly = param_get_data(PAR_ID_BOV_PRP_DLY);
    /* 告警诊断*/
    if(0 == p_data->alm_state)
    {
        if((CURR_DR_DSG != sys_state) && (smp_val >= diag_para.alm_param))
        {
            p_data->alm_time_cnt += cycle;
            if(p_data->alm_time_cnt >= diag_para.alm_dly) 
            {
                p_data->alm_state = 1;
				event_add_to_sram(EVT_ID_ALM_BOV , var_get_data(VAR_ID_BATT_VOLT) , param_get_data(PAR_ID_BOV_ALM_VAL));
                p_data->alm_time_cnt = 0;
				if((diag_get_prp(PRP_ID_COL) == 0))
				{
					soc_calc_set_soc(10000);
                    diag_set_prp(PRP_ID_FULL_CHG , 1);
					diag_set_alarm(ALM_ID_FCHG , 1);
				}
				
				wifi_send_flag = 1;
            }   
        }
        else
        {
            p_data->alm_time_cnt = 0;
        }
    }
    else
    {
		/* 电流小于3A 或 SOC低于98%,解除过压告警 ,低于恢复点电压值 */
        if(((var_get_data(VAR_ID_CURR_DR) == CURR_DR_DSG) && (-now_curr > CHG_RECV_CURR)) 
			|| (var_get_data(VAR_ID_DISP_SOC) * 0.01 < FCHG_RECV_SOC)
			|| (smp_val <= diag_para.alm_recv))	
		{
            p_data->alm_state = 0;
            p_data->alm_time_cnt = 0;
        }
    }
    diag_set_alarm(ALM_ID_BOV , p_data->alm_state);
    /* 保护诊断 */
    if(0 == p_data->prp_state)
    {
        if((CURR_DR_DSG != sys_state) && (smp_val >= diag_para.prp_param))
        {
            p_data->prp_time_cnt += cycle;
            if(p_data->prp_time_cnt >= diag_para.prp_dly) 
            {
                p_data->prp_state = 1;
				bov_times = param_get_data(PAR_ID_BOV_PRP_TIMES) + 1;
				param_set_data(PAR_ID_BOV_PRP_TIMES , bov_times);
				event_add_to_sram(EVT_ID_PRP_BOV , var_get_data(VAR_ID_BATT_VOLT) , param_get_data(PAR_ID_BOV_PRP_VAL));
                p_data->prp_time_cnt = 0;
				if((diag_get_prp(PRP_ID_COL) == 0))
				{
					soc_calc_set_soc(10000);
                    diag_set_prp(PRP_ID_FULL_CHG , 1);
					diag_set_alarm(ALM_ID_FCHG , 1);
				}
				
				wifi_send_flag = 1;
            }   
        }
        else
        {
            p_data->prp_time_cnt = 0;
        }
    }
    else
    {
        if(((CURR_DR_DSG == sys_state) && (-now_curr > CHG_RECV_CURR)) 
			|| (var_get_data(VAR_ID_DISP_SOC) * 0.01 < FCHG_RECV_SOC)
		    || (smp_val <= diag_para.prp_recv))
        {
            p_data->prp_state = 0;
            p_data->prp_time_cnt = 0;
        }
    }

    diag_set_prp(PRP_ID_BOV , p_data->prp_state);
}

/**
 * @brief  总压欠压诊断 
 * @param  cycle  : 时间周期
 * @param  sys_state : 系统状态
 * @param  smp_val : 采样值
 */
void diag_volt_buv(uint16_t cycle)
{
    diag_para_type diag_para = {0};
	diag_data_type *p_data = &diag_buv_data;
	uint8_t sys_state = var_get_data(VAR_ID_CURR_DR);
	uint16_t buv_times = 0;
	float smp_val = var_get_data(VAR_ID_BATT_VOLT) * 0.01; 
	float now_curr = 0;
	
	now_curr = sample_get_curr();//var_get_data(VAR_ID_BUS_CURR) * VAR_CURR_FACTOR - VAR_CURR_OFFSET;	
    diag_para.alm_param = param_convert_float(PARAM_BVOLT , param_get_data(PAR_ID_BUV_ALM_VAL));
    diag_para.alm_recv = param_convert_float(PARAM_BVOLT ,param_get_data(PAR_ID_BUV_ALM_RCV));
    diag_para.alm_dly = param_get_data(PAR_ID_BUV_ALM_DLY);

    diag_para.prp_param = param_convert_float(PARAM_BVOLT ,param_get_data(PAR_ID_BUV_PRP_VAL));
    diag_para.prp_recv = param_convert_float(PARAM_BVOLT ,param_get_data(PAR_ID_BUV_PRP_RCV));
    diag_para.prp_dly = param_get_data(PAR_ID_BUV_PRP_DLY);
    /* 告警诊断*/
    if(0 == p_data->alm_state)
    {
        if((CURR_DR_CHG != sys_state) && (smp_val <= diag_para.alm_param))
        {
            p_data->alm_time_cnt += cycle;
            if(p_data->alm_time_cnt >= diag_para.alm_dly) 
            {
                p_data->alm_state = 1;
				if((diag_get_prp(PRP_ID_COL) == 0) && (var_get_data(VAR_ID_MIN_CELL_VOLT) > 100))
					soc_calc_set_soc(0);
				event_add_to_sram(EVT_ID_ALM_BUV , var_get_data(VAR_ID_BATT_VOLT) , param_get_data(PAR_ID_BUV_ALM_VAL));
                p_data->alm_time_cnt = 0;
				
				wifi_send_flag = 1;
            }   
        }
        else
        {
            p_data->alm_time_cnt = 0;
        }
    }
    else
    {
        if(((CURR_DR_CHG == sys_state)&& (now_curr > DSG_RECV_CURR)) || (smp_val >= diag_para.alm_recv))
        {
            p_data->alm_state = 0;
            p_data->alm_time_cnt = 0;
        }
    }
    diag_set_alarm(ALM_ID_BUV , p_data->alm_state);
    /* 保护诊断 */
    if(0 == p_data->prp_state)
    {
        if((first_pow_flag)&&(CURR_DR_CHG != sys_state) && (smp_val <= diag_para.prp_param))
        {
            p_data->prp_time_cnt += cycle;
            if(p_data->prp_time_cnt >= diag_para.prp_dly) 
            {
                p_data->prp_state = 1;
				buv_times = param_get_data(PAR_ID_BUV_PRP_TIMES) + 1;
				param_set_data(PAR_ID_BUV_PRP_TIMES , buv_times);
				event_add_to_sram(EVT_ID_PRP_BUV , var_get_data(VAR_ID_BATT_VOLT) , param_get_data(PAR_ID_BUV_PRP_VAL));
                p_data->prp_time_cnt = 0;
				if((diag_get_prp(PRP_ID_COL) == 0) && (var_get_data(VAR_ID_MIN_CELL_VOLT) > 100))
					soc_calc_set_soc(0);
				
				wifi_send_flag = 1;
            }   
        }
        else
        {
            p_data->prp_time_cnt = 0;
        }
    }
    else
    {
        if(((CURR_DR_CHG == sys_state) && (now_curr > DSG_RECV_CURR)) 
			|| (smp_val >= diag_para.prp_recv)||(1 == var_get_data(VAR_ID_FAULT_CLEAR_STATE)))
        {
            p_data->prp_state = 0;
            p_data->prp_time_cnt = 0;
			var_set_data(VAR_ID_FAULT_CLEAR_STATE , 0);			
        }
    }

    diag_set_prp(PRP_ID_BUV , p_data->prp_state);
}

/**
 * @brief  压差告警诊断 
 * @param  cycle  : 时间周期
 * @param  sys_state : 系统状态
 * @param  smp_val : 采样值
 */
void diag_volt_vdiff(uint16_t cycle)
{
    diag_para_type diag_para = {0};
	diag_data_type *p_data = &diag_vdiff_data;
	uint16_t smp_val = var_get_data(VAR_ID_MAX_CELL_VOLT) - var_get_data(VAR_ID_MIN_CELL_VOLT);
	
    diag_para.alm_param = param_get_data(PAR_ID_VDIFF_ALM_VAL);
    diag_para.alm_recv = param_get_data(PAR_ID_VDIFF_ALM_RCV);
    diag_para.alm_dly = param_get_data(PAR_ID_VDIFF_ALM_DLY);

    diag_para.prp_param = param_get_data(PAR_ID_VDIFF_PRP_VAL);
    diag_para.prp_recv = param_get_data(PAR_ID_VDIFF_PRP_RCV);
    diag_para.prp_dly = param_get_data(PAR_ID_VDIFF_PRP_DLY);
    /* 告警诊断*/
    if(0 == p_data->alm_state)
    {
        if(smp_val >= diag_para.alm_param)
        {
            p_data->alm_time_cnt += cycle;
            if(p_data->alm_time_cnt >= diag_para.alm_dly) 
            {
                p_data->alm_state = 1;
				event_add_to_sram(EVT_ID_ALM_VDIFF , smp_val , param_get_data(PAR_ID_VDIFF_ALM_VAL));
                p_data->alm_time_cnt = 0;
				
				wifi_send_flag = 1;
            }   
        }
        else
        {
            p_data->alm_time_cnt = 0;
        }
    }
    else
    {
        if(smp_val <= diag_para.alm_recv)
        {
            p_data->alm_state = 0;
        }
    }
    diag_set_alarm(ALM_ID_VDIFF , p_data->alm_state);
	
    /* 保护诊断 */
    if(0 == p_data->prp_state)
    {
        if(smp_val >= diag_para.prp_param)
        {
            p_data->prp_time_cnt += cycle;
            if(p_data->prp_time_cnt >= diag_para.prp_dly) 
            {
                p_data->prp_state = 1;
				event_add_to_sram(EVT_ID_PRP_VDIFF , smp_val , param_get_data(PAR_ID_VDIFF_PRP_VAL));
                p_data->prp_time_cnt = 0;
				
				wifi_send_flag = 1;
            }   
        }
        else
        {
            p_data->prp_time_cnt = 0;
        }
    }
    else
    {
        if((smp_val <= diag_para.prp_recv)||(1 == var_get_data(VAR_ID_FAULT_CLEAR_STATE)))
        {
            p_data->prp_state = 0;
            p_data->prp_time_cnt = 0;
			var_set_data(VAR_ID_FAULT_CLEAR_STATE , 0);			
        }
		
    }

    diag_set_prp(PRP_ID_VDIFF , p_data->prp_state);
}

/** ------------------------------------------------------------------------- *
  *                              Local function
 ** ------------------------------------------------------------------------- */
 
/********** Copyright (c) 2023 JBD-Energy Storage Technology Co. LTD *********/
